﻿#include <iostream>
#include <atomic>
#include <thread>
#include <vector>
#include <windows.h>

using namespace std;

int cnt;
//std::atomic<int> acnt;
atomic_int acnt;

void Add1(std::atomic<int>& cnt)
{
	int old = cnt.load();
	// 如果cnt的值跟old相等，则将cnt的值设置为old+1，并且返回true，这组操作是原⼦的。
	// 那么如果在load和compare_exchange_weak操作之间cnt对象被其他线程改了
	// 则old和cnt不相等，则将old的值改为cnt的值，并且返回false。
	//while (!atomic_compare_exchange_weak(&cnt, &old, old + 1));
	while (!cnt.compare_exchange_weak(old, old + 1));
}
void f()
{
	for (int n = 0; n < 100000; ++n)
	{
		//++acnt;
		// Add1的⽤CAS模拟atomic的operator++的原⼦操作
		Add1(acnt);
		++cnt;
	}
}

void test1()
{
	std::vector<thread> pool;
	for (int n = 0; n < 4; ++n)
		pool.emplace_back(f);
	for (auto& e : pool)
		e.join();
	cout << "原子计数器为 " << acnt << '\n'
		<< "非原子计数器为 " << cnt << '\n';
}


std::atomic<bool> flag(false);
int data1 = 0;

void th1()
{
	Sleep(10);
	// 线程 1
	data1 = 42;
	//flag.store(true, std::memory_order_release);
	flag = true;
}
void th2()
{
	// 线程 2
	//while (!flag.load(std::memory_order_acquire)) {}
	while (!flag.load(std::memory_order_relaxed)) {}
	std::cout << data1; // 保证看到 data = 42
}

void test2()
{
	std::vector<thread> pool;
	pool.emplace_back(th2);
	pool.emplace_back(th1);
	for (auto& e : pool)
		e.join();
}

struct Date
{
	int _year = 1;
	int _month = 1;
	int _day = 1;
};
template < class T>
void check()
{
	cout << typeid(T).name() << endl;
	cout << std::is_trivially_copyable<T>::value << endl;
	cout << std::is_copy_constructible<T>::value << endl;
	cout << std::is_move_constructible<T>::value << endl;
	cout << std::is_copy_assignable<T>::value << endl;
	cout << std::is_move_assignable<T>::value << endl;
	cout << std::is_same<T, typename std::remove_cv<T>::type>::value << endl
		<< endl;
}
void test3()
{
	check<int>();
	check<double>();
	check<int*>();
	check<Date>();
	check<Date*>();
	check<string>();
	check<string*>();
}

int main()
{
	test3();
	return 0;
}
